package 每日一题;

import 我的JDK基础数据结构.HashMap.HashMap;

import java.util.Map;

/**
 * @description: 小白白刷题
 * @author: 小白白
 * @create: 2021-06-16
 **/

public class No877石子游戏 {

    /**
     * 亚历克斯和李用几堆石子在做游戏。偶数堆石子排成一行，每堆都有正整数颗石子 piles[i] 。
     * 游戏以谁手中的石子最多来决出胜负。石子的总数是奇数，所以没有平局。
     * 亚历克斯和李轮流进行，亚历克斯先开始。 每回合，玩家从行的开始或结束处取走整堆石头。
     * 这种情况一直持续到没有更多的石子堆为止，此时手中石子最多的玩家获胜。
     * 假设亚历克斯和李都发挥出最佳水平，当亚历克斯赢得比赛时返回 true ，当李赢得比赛时返回 false 。
     *
     * 示例：
     * 输入：[5,3,4,5]
     * 输出：true
     * 解释：
     * 亚历克斯先开始，只能拿前 5 颗或后 5 颗石子 。
     * 假设他取了前 5 颗，这一行就变成了 [3,4,5] 。
     * 如果李拿走前 3 颗，那么剩下的是 [4,5]，亚历克斯拿走后 5 颗赢得 10 分。
     * 如果李拿走后 5 颗，那么剩下的是 [3,4]，亚历克斯拿走后 4 颗赢得 9 分。
     * 这表明，取前 5 颗石子对亚历克斯来说是一个胜利的举动，所以我们返回 true 。
     *  
     * 提示：
     * 2 <= piles.length <= 500
     * piles.length 是偶数。
     * 1 <= piles[i] <= 500
     * sum(piles) 是奇数。
     */

    public boolean stoneGame(int[] piles) {
        //推荐的dp写法
        /**
         * [i][j]表示当前范围石头堆时,当前玩家的最大收益
         */
        int[][] dp=new int[piles.length][piles.length];

        //base
        for (int i = 0; i < piles.length; i++) {
            dp[i][i]=piles[i];
        }

        //dp
        for (int i = 0; i < piles.length; i++) {
            for (int j = 0; j < i; j++) {
                dp[i][j]=Math.max(piles[j]-dp[i-1][j],piles[j]-dp[i][j+1]);
            }
        }

        return dp[dp.length-1][0]>0;
    }

    private int arrSum;
    private Map<String,Boolean> map=new HashMap<>();

    public boolean stoneGameNorMal(int[] piles) {

        int sum=0;
        for (int pile : piles) {
            sum+=pile;
        }
        this.arrSum =sum;
        return dfs(0,piles.length-1,piles,0);
    }

    private boolean dfs(int left,int right,int[] piles,int sum) {

        if(map.get(left+","+right)!=null){
            return false;
        }

        if(left>right){
            return (double)sum>((double)arrSum/(double) 2);
        }

        /**
         * 拿左边,对方拿左边
         */
        if(dfs(left+2,right,piles,sum+piles[left])){
            return true;
        }

        /**
         * 拿左边,对方拿右边
         */
        if(dfs(left+1,right-1,piles,sum+piles[left])){
            return true;
        }

        /**
         * 拿右边,对象拿左边
         */
        if (dfs(left + 1, right - 1, piles,sum+piles[right])) {
            return true;
        }

        /**
         * 拿右边,对方拿右边
         */
        if(dfs(left,right-2,piles,sum+piles[right])){
            return true;
        }

        /**
         * 记录
         */
        map.put(left+","+right,true);

        return false;
    }

    public static void main(String[] args) {
        No877石子游戏 n=new No877石子游戏();
        int[] arr={216,351,109,383,421,257,324,271,24,161,493,100,499,329,170,183,139,281,449,81,294,191,388,71,178,279,119,342,477,175,62,148,303,468,368,321,120,208,500,417,468,319,470,486,335,389,129,223,59,400,14,461,494,50,208,423,414,148,228,497,30};
        boolean result = n.stoneGame(arr);
        System.out.println(result);
    }

}
